#ifndef __MPU6050_H
#define __MPU6050_H

#include "config.h"

// ========== MPU6050寄存器地址定义 ==========
#define MPU6050_ADDR            0x68    // MPU6050 I2C地址 (AD0=0)
#define MPU6050_ADDR_ALT        0x69    // MPU6050 I2C地址 (AD0=1)

// 常用寄存器
#define MPU6050_SELF_TEST_X     0x0D    // 自检寄存器X
#define MPU6050_SELF_TEST_Y     0x0E    // 自检寄存器Y
#define MPU6050_SELF_TEST_Z     0x0F    // 自检寄存器Z
#define MPU6050_SELF_TEST_A     0x10    // 自检寄存器A
#define MPU6050_SMPLRT_DIV      0x19    // 采样率分频器
#define MPU6050_CONFIG          0x1A    // 配置寄存器
#define MPU6050_GYRO_CONFIG     0x1B    // 陀螺仪配置
#define MPU6050_ACCEL_CONFIG    0x1C    // 加速度计配置
#define MPU6050_FIFO_EN         0x23    // FIFO使能
#define MPU6050_I2C_MST_CTRL    0x24    // I2C主控制
#define MPU6050_INT_PIN_CFG     0x37    // 中断引脚配置
#define MPU6050_INT_ENABLE      0x38    // 中断使能
#define MPU6050_INT_STATUS      0x3A    // 中断状态
#define MPU6050_ACCEL_XOUT_H    0x3B    // 加速度X高字节
#define MPU6050_ACCEL_XOUT_L    0x3C    // 加速度X低字节
#define MPU6050_ACCEL_YOUT_H    0x3D    // 加速度Y高字节
#define MPU6050_ACCEL_YOUT_L    0x3E    // 加速度Y低字节
#define MPU6050_ACCEL_ZOUT_H    0x3F    // 加速度Z高字节
#define MPU6050_ACCEL_ZOUT_L    0x40    // 加速度Z低字节
#define MPU6050_TEMP_OUT_H      0x41    // 温度高字节
#define MPU6050_TEMP_OUT_L      0x42    // 温度低字节
#define MPU6050_GYRO_XOUT_H     0x43    // 陀螺仪X高字节
#define MPU6050_GYRO_XOUT_L     0x44    // 陀螺仪X低字节
#define MPU6050_GYRO_YOUT_H     0x45    // 陀螺仪Y高字节
#define MPU6050_GYRO_YOUT_L     0x46    // 陀螺仪Y低字节
#define MPU6050_GYRO_ZOUT_H     0x47    // 陀螺仪Z高字节
#define MPU6050_GYRO_ZOUT_L     0x48    // 陀螺仪Z低字节
#define MPU6050_USER_CTRL       0x6A    // 用户控制
#define MPU6050_PWR_MGMT_1      0x6B    // 电源管理1
#define MPU6050_PWR_MGMT_2      0x6C    // 电源管理2
#define MPU6050_FIFO_COUNTH     0x72    // FIFO计数高字节
#define MPU6050_FIFO_COUNTL     0x73    // FIFO计数低字节
#define MPU6050_FIFO_R_W        0x74    // FIFO读写
#define MPU6050_WHO_AM_I        0x75    // 设备ID

// ========== 配置参数定义 ==========
// 陀螺仪量程
typedef enum {
    MPU6050_GYRO_FS_250  = 0x00,    // ±250 °/s
    MPU6050_GYRO_FS_500  = 0x08,    // ±500 °/s
    MPU6050_GYRO_FS_1000 = 0x10,    // ±1000 °/s
    MPU6050_GYRO_FS_2000 = 0x18     // ±2000 °/s
} MPU6050_GyroFS_t;

// 加速度计量程
typedef enum {
    MPU6050_ACCEL_FS_2G  = 0x00,    // ±2g
    MPU6050_ACCEL_FS_4G  = 0x08,    // ±4g
    MPU6050_ACCEL_FS_8G  = 0x10,    // ±8g
    MPU6050_ACCEL_FS_16G = 0x18     // ±16g
} MPU6050_AccelFS_t;

// 数字低通滤波器配置
typedef enum {
    MPU6050_DLPF_260HZ = 0,         // 加速度计260Hz, 陀螺仪256Hz
    MPU6050_DLPF_184HZ = 1,         // 加速度计184Hz, 陀螺仪188Hz
    MPU6050_DLPF_94HZ  = 2,         // 加速度计94Hz, 陀螺仪98Hz
    MPU6050_DLPF_44HZ  = 3,         // 加速度计44Hz, 陀螺仪42Hz
    MPU6050_DLPF_21HZ  = 4,         // 加速度计21Hz, 陀螺仪20Hz
    MPU6050_DLPF_10HZ  = 5,         // 加速度计10Hz, 陀螺仪10Hz
    MPU6050_DLPF_5HZ   = 6          // 加速度计5Hz, 陀螺仪5Hz
} MPU6050_DLPF_t;

// 数据结构
typedef struct {
    int16_t x;
    int16_t y;
    int16_t z;
} MPU6050_Data_t;

// ========== 基础I2C函数 ==========
/**
 * @brief I2C总线恢复函数 - 当SDA被拉低时通过切换SCL来恢复总线
 */
extern void MPU6050_I2C_Unlock(void);

/**
 * @brief I2C写入函数
 * @param slaveAddr 从设备地址
 * @param regAddr 寄存器地址
 * @param length 数据长度
 * @param data 数据指针
 * @return 0=成功, -1=失败
 */
extern int MPU6050_I2C_Write(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, const uint8_t *data);

/**
 * @brief I2C读取函数 - 使用硬件自动读取模式(RD_ON_TXEMPTY)
 * @param slaveAddr 从设备地址
 * @param regAddr 寄存器地址
 * @param length 读取长度
 * @param data 数据缓冲区
 * @return 0=成功, -1=失败
 */
extern int MPU6050_I2C_Read(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data);

// ========== MPU6050操作函数 ==========
/**
 * @brief 读取MPU6050单个寄存器
 * @param reg 寄存器地址
 * @return 寄存器值
 */
extern uint8_t MPU6050_ReadReg(uint8_t reg);

/**
 * @brief 写入MPU6050单个寄存器
 * @param reg 寄存器地址
 * @param value 要写入的值
 * @return true=成功, false=失败
 */
extern bool MPU6050_WriteReg(uint8_t reg, uint8_t value);

/**
 * @brief 初始化MPU6050
 * @return true=成功, false=失败
 * @note 会执行以下操作：
 *       1. 检查并恢复I2C总线
 *       2. 复位MPU6050
 *       3. 唤醒设备
 *       4. 配置陀螺仪和加速度计
 *       5. 验证WHO_AM_I
 */
extern bool MPU6050_Init(void);

/**
 * @brief 读取WHO_AM_I寄存器
 * @return 设备ID (正常为0x68)
 */
extern uint8_t MPU6050_GetDeviceID(void);

/**
 * @brief 配置陀螺仪量程
 * @param fs 量程选择
 */
extern void MPU6050_SetGyroFS(MPU6050_GyroFS_t fs);

/**
 * @brief 配置加速度计量程
 * @param fs 量程选择
 */
extern void MPU6050_SetAccelFS(MPU6050_AccelFS_t fs);

/**
 * @brief 配置数字低通滤波器
 * @param dlpf 滤波器配置
 */
extern void MPU6050_SetDLPF(MPU6050_DLPF_t dlpf);

/**
 * @brief 配置采样率
 * @param rate 采样率 (Hz)
 * @note 实际采样率 = 陀螺仪输出率 / (1 + rate)
 *       当DLPF禁用时，陀螺仪输出率为8kHz
 *       当DLPF启用时，陀螺仪输出率为1kHz
 */
extern void MPU6050_SetSampleRate(uint16_t rate);

/**
 * @brief 读取加速度计原始数据
 * @param data 数据结构指针
 */
extern void MPU6050_ReadAccel(MPU6050_Data_t *data);

/**
 * @brief 读取陀螺仪原始数据
 * @param data 数据结构指针
 */
extern void MPU6050_ReadGyro(MPU6050_Data_t *data);

/**
 * @brief 读取温度传感器数据
 * @return 温度值 (°C)
 */
extern float MPU6050_ReadTemp(void);

/**
 * @brief 读取所有传感器数据（一次性读取）
 * @param accel 加速度计数据指针
 * @param gyro 陀螺仪数据指针
 * @param temp 温度指针（可为NULL）
 * @note 一次性读取14字节数据，效率更高
 */
extern void MPU6050_ReadAll(MPU6050_Data_t *accel, MPU6050_Data_t *gyro, float *temp);

#endif // __MPU6050_H
